#include "part3_shared.h"


INI_PARAMS get_params_from_INI_file(const char *filename){
	int status;
	int len;
	char *buf;
	FILE *hIni;
	INI_PARAMS params;

	/* open .ini file and read to buffer */
	hIni = fopen(filename, "rb");
	if (hIni == NULL) {
		perror(filename);
		exit(1);
	}
	
	status = fseek(hIni, 0, SEEK_END);
	if (status != 0) { 
		perror(filename);
		exit(1);
	}
	len = ftell(hIni);
	if (len < 2) {
		fclose(hIni);
		exit(1);
	}
	buf = (char *) malloc((len + 1) * sizeof(char));
	if (buf == NULL) {
		fprintf(stderr, "Error: not enough memory\n");
		exit(1);
	}
	status = fseek(hIni, 0, SEEK_SET);
	if (status != 0) { 
		perror(filename);
		exit(1);
	}
	status = fread(buf, len, 1, hIni);
	if (!status) {
		free(buf);
		fclose(hIni);
		perror(filename);
		exit(1);
	}
	fclose(hIni);
	buf[len] = '\0';

	status = parse_string_value(buf, "LexiconName", params.LexiconName);
	if (status) {
		fprintf(stderr, "Error: Can not find field in %s file: LexiconName=<filename> \n", filename);
		free(buf);
		exit(1);
	}

	params.ChainLength = parse_number_value(buf, "ChainLength");
	if (params.ChainLength < 0) {
		fprintf(stderr, "Error: Can not find field in %s file: ChainLength=<number>\n", filename);
		free(buf);
		exit(1);
	}

	params.NumOfHashEntries = parse_number_value(buf, "NumOfHashEntries");
	if (params.NumOfHashEntries < 0) {
		fprintf(stderr, "Error: Can not find field in %s file: NumOfHashEntries=<number>\n", filename);
		free(buf);
		exit(1);
	}

	params.ElementsInBucket = parse_number_value(buf, "ElementsInBucket");
	if (params.ElementsInBucket < 0) {
		fprintf(stderr, "Error: Can not find field in %s file: ElementsInBucket=<number>\n", filename);
		free(buf);
		exit(1);
	}

	status = parse_string_value(buf, "Rule", params.Rule);
	if (status) {
		fprintf(stderr, "Error: Can not find field in %s file: Rule=<filename> \n", filename);
		free(buf);
		exit(1);
	}

	status = parse_string_value(buf, "MainRandSeed", params.MainRandSeed);
	if (status) {
		fprintf(stderr, "Error: Can not find field in %s file: MainRandSeed=<number>\n", filename);
		free(buf);
		exit(1);
	}

	status = parse_string_value(buf, "HashFunction", params.HashFunction);
	if (status) {
		fprintf(stderr, "Error: Can not find field in %s file: HashFunction=<filename> \n", filename);
		free(buf);
		exit(1);
	}

	status = parse_string_value(buf, "OutputFilePrefix", params.OutputFilePrefix);
	if (status) {
		fprintf(stderr, "Error: Can not find field in %s file: OutputFilePrefix=<filename> \n", filename);
		free(buf);
		exit(1);
	}

	free(buf);
	return params;
}




int parse_string_value(char* buf, char* substring, char* output) {

	char* parameter_name;
	char* parameter_value;
	char* new_line;
	char* equals_sign;
	int length;
	int end_of_buf = 0;

	/* find param name */
	parameter_name = strstr(buf, substring);
	if (!parameter_name) {
		return 1;
	}
	/* next line */
	new_line = strchr(parameter_name, '\n');
	if (!new_line) {
		end_of_buf = 1;
		new_line = strchr(parameter_name, '\0');
	}
	/* find = sign and get value start pointer */
	equals_sign = strchr(parameter_name, '=');
	if (!equals_sign) {
		return 3;
	}
	if(equals_sign > new_line){
		return 2;
	}

	parameter_value = equals_sign+1;

	while (*parameter_value == ' ' || *parameter_value == '\t') {
		parameter_value++;
	}

	/* get value end pointer */
	new_line--;
	while (*new_line == ' ' || *new_line == '\t' || *new_line == '\r') {
		new_line--;
	}
	new_line++;
	*new_line = '\0';

	/* get value */
	length = strlen(parameter_value);

	if (length > MAX_INTPUT_SIZE - 1) {
		return 4;
	}
	strcpy(output, parameter_value);

	if (!end_of_buf)
		*new_line = '\n';

	return 0;
}


int parse_number_value(char* buf, char* substring) {
	int value;

	char* parameter_name;
	char* parameter_value;
	char* new_line;
	char* equals_sign;
	int end_of_buf = 0;

	/* find param name */
	parameter_name = strstr(buf, substring);
	if (!parameter_name) {
		return -1;
	}

	/* next line */
	new_line = strchr(parameter_name, '\n');
	if (!new_line) {
		end_of_buf = 1;
		new_line = strchr(parameter_name, '\0');
	}

	/* find = sign and get value start pointer */
	equals_sign = strchr(parameter_name, '=');
	if (!equals_sign) {
		return -3;
	}

	if(equals_sign > new_line){
		return -2;
	}

	parameter_value = equals_sign+1;

	while (*parameter_value == ' ' || *parameter_value == '\t') {
		parameter_value++;
	}

	/* get value end pointer */
	new_line--;
	while (*new_line == ' ' || *new_line == '\t' || *new_line == '\r') {
		new_line--;
	}
	new_line++;
	*new_line = '\0';
	value = atoi(parameter_value);
	if (value == 0) {
		return -4;
	}
	if (!end_of_buf)
		*new_line = '\n';

	return value;
}
